package com.holly.aop;

import com.holly.pojo.OperateLog;
import com.holly.mapper.OperateLogMapper;
import com.holly.util.CurrentHolder;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Arrays;

@Slf4j
@Aspect
@Component
public class OperationLoggingAspect {

    @Autowired
    private OperateLogMapper operateLogMapper;

    @Around("@annotation(com.holly.anno.Log)")
    public Object logOperation(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取当前时间作为开始时间
        LocalDateTime startTime = LocalDateTime.now();

        // 获取执行的方法签名
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String className = signature.getDeclaringTypeName();
        String methodName = signature.getName();

        // 获取方法参数
        Object[] args = joinPoint.getArgs();
        String methodParams = Arrays.toString(args);

        // 操作人ID（这里假设从某个地方获取，例如SecurityContext）
        int operateEmpId = getOperateEmpId(); // 需要根据实际情况实现

        try {
            // 执行目标方法
            Object result = joinPoint.proceed();

            // 记录成功日志
            recordLog(joinPoint, startTime, className, methodName, methodParams, result, null);

            return result;
        } catch (Exception e) {
            // 记录异常日志
            recordLog(joinPoint, startTime, className, methodName, methodParams, null, e.getMessage());

            throw e;
        }
    }

    private void recordLog(ProceedingJoinPoint joinPoint, LocalDateTime startTime, String className, String methodName, String methodParams, Object result, String errorMessage) {
        // 获取结束时间
        LocalDateTime endTime = LocalDateTime.now();

        // 计算方法执行耗时
        long costTime = java.time.Duration.between(startTime, endTime).toMillis();

        // 构造OperateLog对象
        OperateLog operateLog = new OperateLog();
        operateLog.setOperateEmpId(getOperateEmpId()); // 需要根据实际情况实现
        operateLog.setOperateTime(startTime);
        operateLog.setClassName(className);
        operateLog.setMethodName(methodName);
        operateLog.setMethodParams(methodParams);
        operateLog.setReturnValue(result != null ? result.toString() : "void");
        operateLog.setCostTime(costTime);

        if (errorMessage != null) {
            operateLog.setReturnValue(errorMessage);
        }

        log.info("记录操作日志: {}", operateLog);
        // 插入日志记录
        operateLogMapper.insert(operateLog);
    }

    private int getOperateEmpId() {
        // 这里需要根据实际情况获取操作人ID，例如从SecurityContext中获取
        // 示例中返回一个固定的值
        //return CurrentHolder.getCurrentId();
        return 1;
    }
}



